package edu.hawaii.myisern.action;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

/**
 * A simplistic security filter for the MyISERN system that ensures that the user is logged in 
 * before allowing accessing any secured pages.  This class was adapted from the Bugzooky example.  
 * 
 * @author Tim Fennell
 * @author Laura Matsuo
 */
public class SecurityFilter implements Filter {
  private static Set<String> publicUrls = new HashSet<String>();

  static {
    publicUrls.add("/login.jsp");
    publicUrls.add("/index.jsp");
    publicUrls.add("/Login.action");
    publicUrls.add("/logout.jsp");
    publicUrls.add("/Logout.action");
  }

  /** 
   * Does nothing.
   * 
   * @param filterConfig       The FilterConfig object.
   * @throws ServletException  A ServletException.
   */
  public void init(FilterConfig filterConfig) throws ServletException {
    //does nothing.
  }

  /**
   * Filters the request and ensures that the user is logged in before they can access restricted
   * pages.
   * 
   * @param servletRequest     The ServletRequest object.
   * @param servletResponse    The ServletResponse object.
   * @param filterChain        The FilterChain object.
   * @throws IOException       If an error occurs.
   * @throws ServletException  If an error occurs.
   */
  @SuppressWarnings("PMD")
  public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
      FilterChain filterChain) throws IOException, ServletException {
    HttpServletRequest request = (HttpServletRequest) servletRequest;
    HttpServletResponse response = (HttpServletResponse) servletResponse;

    // suppress the PMD error about !=
    if (request.getSession().getAttribute("user") != null) {
      filterChain.doFilter(request, response);
    }
    else if (isPublicResource(request)) {
      filterChain.doFilter(request, response);
    }
    else {
      // Redirect the user to the login page, noting where they were coming from
      // String targetUrl = URLEncoder.encode(request.getServletPath(), "UTF-8");

      response.sendRedirect(request.getContextPath() + "/logout.jsp");
    }
  }

  /**
   * Method that checks the request to see if it is for a publicly accessible resource.
   * 
   * @param request  The HttpServletReqest object.
   * @return         True if the request is a public resource, otherwise false.
   */
  protected boolean isPublicResource(HttpServletRequest request) {
    String resource = request.getServletPath();

    return publicUrls.contains(request.getServletPath())
    || (!resource.endsWith(".jsp") && !resource.endsWith(".action"));
  }

  /** Does nothing. */
  public void destroy() {
    // does nothing
  }
}
